﻿using Newtonsoft.Json;
using System.ComponentModel;
using System.Windows;
using VisionDesigner;
using VisionDesigner.ImageBinary;
using VM.Common.Enums;
using VM.Common.EventMgrLib;
using VM.Common.Helper;
using VM.Dialogs.Views;
using VM.Start.Attributes;
using VM.Start.Common;
using VM.Start.Core;
using VM.Start.Events;
using VM.Start.ViewModels;


namespace Plugin.Binary
{

    #region enum
    public enum eLinkCommand
    {
        InputImageLink,
        PositionFix
    }

    #endregion

    [Category("图像处理")]
    [DisplayName("二值化")]
    [ModuleImageName("Binary")]
    [JsonObject(MemberSerialization.OptOut)]
    public class BInaryViewModel : ModuleBase
    {
        #region  属性
        private CImageBinaryTool _Binart_toolobj;
        private CImageBinaryTool Binart_toolobj
        {
            get
            {
                try
                {
                    if (_Binart_toolobj == null)
                    {
                        _Binart_toolobj = new CImageBinaryTool();
                    }
                }
                catch (MvdException ex)
                {
                    if (ex.ErrorCode == MVD_ERROR_CODE.MVD_E_RUNTIME)
                    {
                        MessageView.Ins.MessageBoxShow("运行环境异常，请停止项目并检查加密狗！", eMsgType.Error);
                    }
                    else
                    {
                        MessageView.Ins.MessageBoxShow("创建实例失败！", eMsgType.Error);
                    }
                }
                return _Binart_toolobj;
            }
        }

        private CMvdImage m_stBinaryImage = null;
        /// <summary>
        /// 参数
        /// </summary>
        private ParamModel _Param;
        public ParamModel Param
        {
            get
            {
                if (_Param == null)
                {
                    _Param = new ParamModel();
                }
                return _Param;
            }
            set
            {
                Set(ref _Param, value);
            }
        }
        #endregion
        #region  数据接口



        private Array _OutImgTypes = Enum.GetValues(typeof(OutImageTypes));
        public Array OutImgTypes
        {
            get { return _OutImgTypes; }
            set { Set(ref _OutImgTypes, value); }
        }

        private OutImageTypes _OutImgType = OutImageTypes.二值化图像;
        public OutImageTypes OutImgType
        {
            get { return _OutImgType; }
            set
            {
                Set(ref _OutImgType, value);
                UpdateOutImage();
            }
        }

        /// <summary>
        /// ROI
        /// </summary>
        public CMvdShape ROI;
        private ROITypeEnum _ROIType = ROITypeEnum.全图;
        public ROITypeEnum ROIType
        {
            get { return _ROIType; }
            set
            {
                mWindowH.ROI = ROI;
                Set(ref _ROIType, value, new Action(() =>
                {
                    switch (_ROIType)
                    {
                        case ROITypeEnum.全图:
                            mWindowH.ROIType = ROITypeEnum.全图;
                            break;
                        case ROITypeEnum.矩形:
                            mWindowH.ROIType = ROITypeEnum.矩形;
                            break;
                        default:
                            break;
                    }
                }));
            }
        }

        #endregion
        #region 指令
        [Newtonsoft.Json.JsonIgnore]
        private CommandBase _LinkCommand;
        [Newtonsoft.Json.JsonIgnore]
        public CommandBase LinkCommand
        {
            get
            {
                if (_LinkCommand == null)
                {
                    //以GUID+类名作为筛选器
                    EventMgr.Ins.GetEvent<VarChangedEvent>().Subscribe(OnVarChanged, o => o.SendName.StartsWith($"{ModuleGuid}"));
                    _LinkCommand = new CommandBase((obj) =>
                    {
                        eLinkCommand linkCommand = (eLinkCommand)obj;
                        switch (linkCommand)
                        {
                            case eLinkCommand.InputImageLink:
                                CommonMethods.GetModuleList(ModuleParam, VarLinkViewModel.Ins.Modules, "Image");
                                EventMgr.Ins.GetEvent<OpenVarLinkViewEvent>().Publish($"{ModuleGuid},InputImageLink");
                                break;
                            case eLinkCommand.PositionFix:
                                CommonMethods.GetModuleList(ModuleParam, VarLinkViewModel.Ins.Modules, "CPositionFixTool");
                                EventMgr.Ins.GetEvent<OpenVarLinkViewEvent>().Publish($"{ModuleGuid},PositionFix");
                                break;
                            default:
                                break;
                        }
                    });
                }
                return _LinkCommand;
            }
        }

        [Newtonsoft.Json.JsonIgnore]
        private CommandBase _ExecuteCommand;
        [Newtonsoft.Json.JsonIgnore]
        public CommandBase ExecuteCommand
        {
            get
            {
                if (_ExecuteCommand == null)
                {
                    _ExecuteCommand = new CommandBase((obj) =>
                    {
                        ExeModule();
                    });
                }
                return _ExecuteCommand;
            }
        }

        [Newtonsoft.Json.JsonIgnore]
        private CommandBase _ConfirmCommand;
        [Newtonsoft.Json.JsonIgnore]
        public CommandBase ConfirmCommand
        {
            get
            {
                if (_ConfirmCommand == null)
                {
                    _ConfirmCommand = new CommandBase((obj) =>
                    {
                        var view = this.ModuleView as BinaryView;
                        if (view != null)
                        {
                            view.Close();
                        }
                    });
                }
                return _ConfirmCommand;
            }
        }
        #endregion
        #region 方法
        public override void Loaded()
        {
            base.Loaded();
            var view = ModuleView as BinaryView;
            if (view != null)
            {
                ClosedView = true;
                if (DispImage == null)
                {
                    SetDefaultLink();
                    if (InputImageLinkText == null) return;
                }
                GetDispImage(InputImageLinkText, true);
            }
        }

        public override void SetDefaultLink()
        {
            if (InputImageLinkText == null)
            {
                CommonMethods.GetModuleList(ModuleParam, VarLinkViewModel.Ins.Modules, "Image");
                var moduls = VarLinkViewModel.Ins.Modules.LastOrDefault();
                if (moduls?.VarModels.Count > 0)
                {
                    InputImageLinkText = $"&{moduls.DisplayName}.{moduls.VarModels[0].Name}";
                }
            }

            if (PositionFixText == null)
            {
                CommonMethods.GetModuleList(ModuleParam, VarLinkViewModel.Ins.Modules, "CPositionFixTool");
                var moduls = VarLinkViewModel.Ins.Modules.LastOrDefault();
                if (moduls?.VarModels.Count > 0)
                {
                    PositionFixText = $"&{moduls.DisplayName}.{moduls.VarModels[0].Name}";
                }
            }
        }

        private void OnVarChanged(VarChangedEventParamModel obj)
        {
            switch (obj.SendName.Split(',')[1])
            {
                case "InputImageLink":
                    InputImageLinkText = obj.LinkName;
                    if (InputImageLinkText == null) return;
                    GetDispImage(InputImageLinkText, true);
                    break;
                case "PositionFix":
                    PositionFixText = obj.LinkName;
                    if (PositionFixText == null) return;
                    GetPositionFix(PositionFixText);
                    break;
                default:
                    break;
            }
        }
        public override bool ExeModule()
        {
            try
            {
                Stopwatch.Restart();
                Application.Current.Dispatcher.Invoke(() =>
                {
                    mWindowH.Clear();
                    if (InputImageLinkText != null)
                    {
                        GetDispImage(InputImageLinkText, true);
                    }
                    else
                    {
                        SetDefaultLink();
                    }
                });

                if (null == Binart_toolobj || (DispImage == null))
                {
                    ChangeModuleRunStatus(eRunStatus.NG);
                    return false;
                }
                Binart_toolobj.InputImage = DispImage;
                //判断ROI 将roi赋值给需要二值化的图片
                if (IsPositionFix && PositionFixTool != null && mWindowH.ROI != null)
                {
                    PositionFixTool.BasicParam.InitialShape = mWindowH.ROI;
                    PositionFixTool.Run();
                    mWindowH.PositionFixROI = PositionFixTool.Result.CorrectedShape;
                    Binart_toolobj.ROI = mWindowH.PositionFixROI;
                }
                else
                {
                    Binart_toolobj.ROI = mWindowH.ROI;
                }
                ROI = mWindowH.ROI;

                Binart_toolobj.ClearMasks();
                Param.Binaryupdata(Binart_toolobj);
                Binart_toolobj.Run();
                m_stBinaryImage = Binart_toolobj.Result.OutputImage;

                Application.Current.Dispatcher.Invoke(() =>
                {
                    UpdateOutImage();
                });

                ChangeModuleRunStatus(eRunStatus.OK);
                return true;
            }
            catch
            {
                ChangeModuleRunStatus(eRunStatus.NG);
                return false;
            }
        }

        public override bool ExeModule(string TemplateName)
        {
            return ExeModule();
        }

        public override void AddOutputParams()
        {
            base.AddOutputParams();
            AddOutputParam("二值化图像", "Image", m_stBinaryImage);
        }

        private void UpdateOutImage()
        {
            try
            {
                switch (OutImgType)
                {
                    case OutImageTypes.原图:
                        mWindowH.Image = DispImage;
                        //mWindowH.DrawRectangleFList(m_lBlobBoxRender1);
                        break;
                    case OutImageTypes.二值化图像:
                        if (m_stBinaryImage != null)
                        {
                            mWindowH.Image = m_stBinaryImage;
                        }
                        break;

                    default:
                        break;
                }
            }
            catch
            {

            }
        }

        #endregion
    }
}
